#include "SemanticNodeVariableName.h"

#include "main2.h"


SemanticNodeVariableName::SemanticNodeVariableName(const SyntaxTreeNode *variableNameNode, SemanticNode *parent) : SemanticNode(parent), ValueType(getNextUniqueID()) {
	std::vector<const SyntaxTreeNode *> VV = findVVs(variableNameNode);
	for (std::vector<const SyntaxTreeNode *>::iterator i = VV.begin(); i != VV.end(); ++i) {
		std::vector<std::string> res = flattenNameAmbiguous((*i)->Nodes->GetData(0));
		if (res.size() != 0) {
			flatNames.push_back(res);
			if ((*i)->Nodes->GetCount() > 1) {
			 std::vector<const SyntaxTreeNode *> vstn;
			 for (int x = 0; x < (*i)->Nodes->GetData(1)->Nodes->GetCount(); ++x) {
					vstn.push_back((*i)->Nodes->GetData(1)->Nodes->GetData(x)->Nodes->GetData(1));
			 }
			 expressions.push_back(vstn);
			}
		}
	}
}
/**
 *  @fn	std::vector<std::string> SemanticNodeVariableName::flattenNameAmbiguous(const SyntaxTreeNod
 *  	e *nameAmbiguousNode)
 *
 *  @brief	Flatten name ambiguous.
 *
 *  @author	Nikola Novak
 *  @date	6/16/2009
 *
 *  @param	nameAmbiguousNode	If non-null, the name ambiguous node.
 *
 *  @return	Names.
 */
std::vector<std::string> SemanticNodeVariableName::flattenNameAmbiguous(const SyntaxTreeNode *nameAmbiguousNode) {
	std::vector<std::string> res;
//	std::string a = CompilerData->Units->GetLexicUnitString(&CompilerData->Units->GetLexicUnit(nameAmbiguousNode->LexUnitID));
	LexicUnit lu = CompilerData->Units->GetLexicUnit(nameAmbiguousNode->Nodes->GetData(0)->LexUnitID);
	res.push_back(CompilerData->Units->GetLexicUnitString(&lu));
	for (int x = 0; x < nameAmbiguousNode->Nodes->GetData(1)->Nodes->GetCount(); ++x) {
		LexicUnit lu = CompilerData->Units->GetLexicUnit(nameAmbiguousNode->Nodes->GetData(1)->Nodes->GetData(x)->Nodes->GetData(1)->LexUnitID);
		res.push_back(CompilerData->Units->GetLexicUnitString(&lu));
	}
	return res;
}

/**
 *  @fn	std::vector<const SyntaxTreeNode*> SemanticNodeVariableName::findVVs(const SyntaxTreeNode *r
 *  	ootVV)
 *
 *  @brief	Searches for all VVs.
 *
 *  @author	Nikola Novak
 *  @date	6/16/2009
 *
 *  @param	rootVV	If non-null, the root VV.
 *
 *  @return	Empty std::vector if it fails, else the found VVs.
 */
std::vector<const SyntaxTreeNode *> SemanticNodeVariableName::findVVs(const SyntaxTreeNode *rootVV) {
	std::vector<const SyntaxTreeNode *> res;
	res.push_back(rootVV);
	const SyntaxTreeNode *cur = rootVV;
	//if (cur->Nodes->GetCount() > 2) {
	 while ((cur = cur->Nodes->GetData(2)->Nodes->GetData(0)) != NULL) {
	 	cur = cur->Nodes->GetData(1);
	 	res.push_back(cur);
	 }
	//}
	return res;
}
/**
 *  @fn	void SemanticNodeVariableName::addExpression(SemanticNodeExpression *expr, int x, int y)
 *
 *  @brief	Adds an expression.
 *
 *  @author	Nikola Novak
 *  @date	6/16/2009
 *
 *  @param	expr	If non-null, the expr.
 *  @param	x		The x coordinate.
 *  @param	y		The y coordinate.
 */
void SemanticNodeVariableName::addExpression(SemanticNodeExpression *expr, int x, int y) {
	if (x > dimensions.size()) return;
	else if (x == dimensions.size()) {
		std::vector<SemanticNodeExpression *> newV;
		dimensions.push_back(newV);
	}
	dimensions[x].push_back(expr);
}
/**
 *  @fn	std::vector<std::vector<constSyntaxTreeNode*>> SemanticNodeVariableName::getExpressions(voi
 *  	d)
 *
 *  @brief	Gets the expressions.
 *
 *  @author	Nikola Novak
 *  @date	6/16/2009
 *
 *  @return	null if it fails, else the expressions.
 */
std::vector<std::vector<const SyntaxTreeNode *> > SemanticNodeVariableName::getExpressions(void) {
	return expressions;
}

/**
 *  @fn	std::string SemanticNodeVariableName::toDebugString(int tab)
 *
 *  @brief	Converts a tab to a debug string.
 *
 *  @author	Nikola Novak
 *  @date	6/16/2009
 *
 *  @param	tab	The tab.
 *
 *  @return	This object as a std::string.
 */
std::string SemanticNodeVariableName::toDebugString(int tab) {
	std::ostringstream res;
	for (int i = 0; i < tab; i++) res << DEBUG_STRING_RAZMAK;
	unsigned int x = 0;
	for (std::vector<std::vector<std::string> >::iterator i = flatNames.begin(); i != flatNames.end(); ++x) {
		for (std::vector<std::string>::iterator t = (*i).begin(); t != (*i).end(); ) {
			res << *t;
			if (++t != (*i).end()) res << ".";
			else {
				if (x < dimensions.size()) {
					res << "[" << std::endl;
					for (std::vector<SemanticNodeExpression *>::iterator e = dimensions[x].begin(); e != dimensions[x].end(); ) {
						res << ((SemanticNode *)(*e))->toDebugString(tab + 1);
						for (int i = 0; i < tab; i++) res << DEBUG_STRING_RAZMAK;
						if (++e != dimensions[x].end()) res << "][" << std::endl;
					}
				 res << "]";
				}
			}
		}
		if (++i != flatNames.end()) res << ".";
	}
	res << std::endl;
	//res << convDebug(tab, syntaxNode);
	return res.str();
}
std::string SemanticNodeVariableName::convDebug(int tab, const SyntaxTreeNode &node) {
	std::ostringstream res;
	for (int i = 0; i < tab; i++) res << DEBUG_STRING_RAZMAK;
	if (node.LexUnitID == -1)	res << CompilerData->SyntaxTree->ConvertProductionToString(node.Production) << std::endl;
	else	res << CompilerData->Units->GetLexicUnitString(node.LexUnitID) << std::endl;
	for (int x = 0; x < node.Nodes->GetCount(); ++x) {
		res << convDebug(tab + 1, *node.Nodes->GetData(x));
	}
	return res.str();
}
